package 深拷贝;

public class TestClass {
    public static void main(String[] args) {
        /*
            clone方法 --> 复制当前对象并返回
            clone方法是native方法,native方法的效率远高于非native方法,因此还是使用clone方法去做对象的拷贝而不是使用new的方法拷贝

            浅拷贝:被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象,换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象

            深拷贝:被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量,那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象,换言之,深复制把要复制的对象所引用的对象都复制了一遍
         */
        Address address = new Address();
        address.setAddress("苏州大学");

        Person person = new Person();
        person.setName("人员1");
        person.setAge(33);
        person.setAddress(address);

        try {
            Person newPerson = (Person)person.clone();  //不为同一个对象

            Address oldAddress = person.getAddress();
            Address newAddress = newPerson.getAddress();
            System.out.println(oldAddress == newAddress);

        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }


    }
}

class Address implements Cloneable{ //需要实现Cloneable接口

    private String address;

    public void setAddress(String address) {
        this.address = address;
    }

    public String getAddress() {
        return address;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

class Person implements Cloneable{ //需要实现Cloneable接口,clone()是Object类中的protected成员方法,实现Cloneable只是为了运行时不要报异常

    private String name;
    private Integer age;
    private Address address;  //引入Address

    public void setName(String name) {
        this.name = name;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

    public String getName() {
        return name;
    }

    public Integer getAge() {
        return age;
    }

    public Address getAddress() {
        return address;
    }


    @Override
    protected Object clone() throws CloneNotSupportedException {
        Person newPerson = (Person)super.clone();
        newPerson.address = (Address)this.address.clone(); //手动在clone方法里拷贝引用类型,引用类型也要实现
        return newPerson;
    }
}

